package fr.alesia.deepstack.bean.jdo;

import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.NotPersistent;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import fr.alesia.deepstack.bean.Player;
import fr.alesia.deepstack.bean.Ranking;
import fr.alesia.deepstack.bean.Tournament;
import fr.alesia.deepstack.factory.ServiceFactory;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class RankingJdo implements Ranking {

	@PrimaryKey
	@Persistent //(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private String id;
	
	@NotPersistent
	private Player player;
	
	@NotPersistent
	private Tournament tournament;
	
	@Persistent
	private Integer rank;
	
	@Persistent
	private String playerId;
	
	@Persistent
	private String tournamentId;
	
	public RankingJdo(Player player, Tournament tournament, Integer rank) {

		this.player = player;
		this.refreshPlayerId();
		
		this.tournament = tournament;
		this.refreshTournamentId();
		
		this.rank = rank;
	}

	public Player getPlayer() {
		return player;
	}

	public Integer getPoints() {
		
		int n = ServiceFactory.getTournamentService(tournament).getNbPlayers();
		int points = (n - rank) + (rank == 1 ? 2 : 1); 
		return points;
	}

	public Integer getRank() {
		return rank;
	}

	public Tournament getTournament() {
		return tournament;
	}

	public void setPlayer(Player player) {
		this.player = player;
		this.refreshPlayerId();
	}

	public void setRank(Integer rank) {
		this.rank = rank;
	}

	public void setTournament(Tournament tournament) {
		this.tournament = tournament;
		this.refreshTournamentId();
	}

	public String getId() {
		return id;
	}
	
	public void setId(String id) {
		this.id = id;
	}

	public int compareTo(Ranking other) {

		return this.compare(this, other);
	}

	public int compare(Ranking r1, Ranking r2) {
		
		if(r1.equals(r2)){
			
			return 0;
		}
		else{
			
			if(r1.getTournament().equals(r2.getTournament())){
				if(r1.getRank().equals(r2.getRank())){
					return r1.getPlayer().compareTo(r2.getPlayer());
				}
				else{
					return r1.getRank().compareTo(r2.getRank());
				}
			}
			else{
				return r1.getTournament().compareTo(r2.getTournament());
			}
		}
	}
	
	public String getPlayerId() {
		return playerId;
	}

	public void setPlayerName(String playerId) {
		this.playerId = playerId;
	}

	public String getTournamentId() {
		return tournamentId;
	}

	public void setTournamentId(String tournamentId) {
		this.tournamentId = tournamentId;
	}

	private void refreshPlayerId(){
		this.playerId = this.player.getId();
	}
	
	private void refreshTournamentId(){
		this.tournamentId = this.tournament.getId();
	}
	
	@Override
	public String toString() {
		
		return "[" + tournament + "] " + rank + " : " + player.getName();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((player == null) ? 0 : player.hashCode());
		result = prime * result + ((tournament == null) ? 0 : tournament.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		RankingJdo other = (RankingJdo) obj;
		if (player == null) {
			if (other.player != null)
				return false;
		} else if (!player.equals(other.player))
			return false;
		if (tournament == null) {
			if (other.tournament != null)
				return false;
		} else if (!tournament.equals(other.tournament))
			return false;
		return true;
	}
}
